using System;
using System.Collections.Generic;

namespace Karma.Framework.Core.Modules.Reports.Definition.Expression
{
    internal class BinaryExpression: ExpressionBase
    {
        protected string _operator;

        protected IExpression _leftexp;

        protected IExpression _rightexp;

        public BinaryExpression(Criteria criteria, string op)
            : base(criteria)
        {
            if (criteria.Criterions == null)
            {
                throw new ArgumentException(
                    string.Format("{0}. The expression must be composed by 2 inner expressions but it is null.", 
                                  GetType().Name));
            }
            if (criteria.Criterions.Count != 2)
            {
                throw new ArgumentException(string.Format(
                                                "{0}. The expression must be composed by 2 inner expressions but it has [{1}].",
                                                GetType().Name, criteria.Criterions.Count));
            }
            if (criteria.Criterions == null)
            {
                throw new ArgumentException(string.Format("{0}. The operator cant be null.", GetType().Name));
            }
            _operator = op;
            _leftexp = ExpressionBuilder.Build(_criteria.Criterions[0]);
            _rightexp = ExpressionBuilder.Build(_criteria.Criterions[1]);
        }

        public override CompiledExpression Compile(Report report)
        {
            var exp = new CompiledExpression
                          {
                              Parameters = new Dictionary<string, object>()
                          };
            var compiled1 = _leftexp.Compile(report);
            var compiled2 = _rightexp.Compile(report);

            exp.Expression = string.Format("{0} {1} {2}", compiled1.Expression, _operator, compiled2.Expression);

            if (compiled1.Parameters != null && compiled1.Parameters.Count > 0)
            {
                foreach (var key in compiled1.Parameters.Keys)
                {
                    exp.Parameters.Add(key, compiled1.Parameters[key]);
                }
            }
            if (compiled2.Parameters != null && compiled2.Parameters.Count > 0)
            {
                foreach (var key in compiled2.Parameters.Keys)
                {
                    exp.Parameters.Add(key, compiled2.Parameters[key]);
                }
            }
            return exp;
        }
    }
}
